package com.gt.qr;

import java.io.IOException;

import com.google.zxing.client.android.CaptureActivityHandler;
import com.google.zxing.client.android.camera.CameraManager;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;

public class QrCodeCameraView extends SurfaceView implements
		SurfaceHolder.Callback {

	private static final String TAG="QrCodeCameraView";
	
	private SurfaceHolder mSurfaceHolder;
	private boolean hasSurface;
	
	private boolean isNeedInitCamera=true;
	
	private QrCodeHandler qrCodeHandler=null;
	
	private QrCodeListener listener=null;
	
	private Display screenDisplay;
	private Point screenResolution;
	private View framingView;
	
	public QrCodeCameraView(Context context, AttributeSet attrs) {
		super(context, attrs);

		mSurfaceHolder = super.getHolder();
		mSurfaceHolder.addCallback(this);
		mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

		hasSurface = false;

		WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		screenDisplay= manager.getDefaultDisplay();
		screenResolution=new Point(screenDisplay.getWidth(),screenDisplay.getHeight());
	}
	
	public static void init(Context context) {
		CameraManager.init(context);
	}
	
	public void setFramingView(View view){
		this.framingView=view;
	}
	
	public void setQrCodeListener(QrCodeListener listener){
		this.listener=listener;
	}
	
	final void onQrCodeCatched(String content){
		if(listener!=null){
			listener.onQrCodeCatched(this, content);
		}
	}
	
	public void onResume() {
		if(!isNeedInitCamera){
			return;
		}
		
		SurfaceHolder surfaceHolder = super.getHolder();
		if (hasSurface) {
			// The activity was paused but not stopped, so the surface still
			// exists. Therefore
			// surfaceCreated() won't be called, so init the camera here.
			initCamera(surfaceHolder);
		}
		isNeedInitCamera=false;

	}

	public void onPause() {
		Log.e(TAG, "onPause>>>");
		isNeedInitCamera=true;
		
//		if (handler != null) {
//			handler.quitSynchronously();
//			handler = null;
//		}
		if(qrCodeHandler!=null){
			qrCodeHandler.stop();
			qrCodeHandler=null;
		}
		CameraManager.get().stopPreview();
		
		CameraManager.get().closeDriver();
	}

	public void onDestroy() {

		CameraManager.destroyCurrentInstance();
		Log.e(TAG, "onDestroy>>>");
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		if (!hasSurface) {
			hasSurface = true;
			initCamera(holder);
//			CameraManager.get().create();
		}
		if(framingView!=null){
			this.setFramingRectByView(framingView);
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		Log.e(TAG, "surfaceChanged>>>");
		
//		onPause();
//		onResume();
		
//		CameraManager.get().onSurfaceChanged(width, height);
		try {
			CameraManager.get().onChanged(holder, format, width, height);
		} catch (IOException e) {
			Log.e(TAG, "surfaceChanged>>>e="+e.toString());
			e.printStackTrace();
		}
//		if (!hasSurface) {
//			hasSurface = true;
//			initCamera(holder);
//		}
		if(framingView!=null){
			this.setFramingRectByView(framingView);
		}
		
		
//		try {
//			CameraManager.get().create();
//			CameraManager.get().onChanged(holder, format, width, height);
//			CameraManager.get().startPreview();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		Log.e(TAG, "surfaceDestroyed>>>");
		hasSurface = false;
		
		
		this.onPause();
	}
	
	private void initCamera(SurfaceHolder surfaceHolder) {
		try {
			
			
			CameraManager.get().openDriver(surfaceHolder);
			
			CameraManager.get().stopPreview();//must call this method after openDriver(). Otherwise occurs a exception on the second time started.
			
		} catch (IOException ioe) {
			Log.w(TAG, ioe);
			return;
		} catch (RuntimeException e) {
			Log.w(TAG, "Unexpected error initializating camera", e);
			return;
		}
		if (qrCodeHandler == null) {
			qrCodeHandler=new QrCodeHandler(this);
			qrCodeHandler.start();
		}
	}
	
	public void setFramingRect(Rect rect){
		CameraManager.get().setFramingRect(rect);
	}
	
	private void setFramingRectByView(View view) {
//		Rect framingRect = new Rect(view.getLeft(), view.getTop(), 
//				view.getRight(), view.getBottom());
		Rect framingRect=new Rect();
		view.getGlobalVisibleRect(framingRect);
		
//		int width = screenResolution.x * 3 / 4;
//		if (width < MIN_FRAME_WIDTH) {
//			width = MIN_FRAME_WIDTH;
//		} else if (width > MAX_FRAME_WIDTH) {
//			width = MAX_FRAME_WIDTH;
//		}
//		int height = screenResolution.y * 3 / 4;
//		if (height < MIN_FRAME_HEIGHT) {
//			height = MIN_FRAME_HEIGHT;
//		} else if (height > MAX_FRAME_HEIGHT) {
//			height = MAX_FRAME_HEIGHT;
//		}
//		int leftOffset = (screenResolution.x - width) / 2;
//		int topOffset = (screenResolution.y - height) / 2;
//		framingRect = new Rect(leftOffset, topOffset, leftOffset + width,
//				topOffset + height);
		
		Log.d(TAG, "setFramingRectByView>>>Calculated framing rect: " + framingRect);
		this.setFramingRect(framingRect);
	}
	
	public Bitmap getLastImage(){
		return qrCodeHandler.getLastBitmap();
	}
	
}
